package com.sunda.spmsoversea.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsoversea.dto.OverseaRequisitionDTO;
import com.sunda.spmsoversea.dto.OverseaRequisitionDtlDTO;
import com.sunda.spmsoversea.dto.OverseaRequisitionQueryDTO;
import com.sunda.spmsoversea.entity.OverseaRequisition;
import com.sunda.spmsoversea.entity.OverseaRequisitionDtl;
import com.sunda.spmsoversea.mapper.OverseaRequisitionMapper;
import com.sunda.spmsoversea.service.IOverseaOperateLogService;
import com.sunda.spmsoversea.service.IOverseaRequisitionDtlService;
import com.sunda.spmsoversea.service.IOverseaRequisitionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.sunda.spmsoversea.constant.CommonConstant.SUCCESS;
import static com.sunda.spmsoversea.enums.OverseaRequisitionEnum.*;

/**
 * <p>
 * 领用申请表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-09-22
 */
@Service
public class OverseaRequisitionServiceImpl extends ServiceImpl<OverseaRequisitionMapper, OverseaRequisition> implements IOverseaRequisitionService {

    @Autowired
    IOverseaRequisitionDtlService iOverseaRequisitionDtlService;

    @Autowired
    IOverseaOperateLogService iOverseaOperateLogService;

    @Override
    public IPage getOverseaRequisitionPage(OverseaRequisitionQueryDTO overseaRequisitionQueryDTO) {
        IPage iPage = overseaRequisitionQueryDTO.getPage();
        List<Map<String, Object>> mapList = this.baseMapper.getOverseaRequisitionIPage(iPage, overseaRequisitionQueryDTO);
        iPage.setRecords(mapList);
        return iPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult createOverseaRequisition(OverseaRequisitionDTO overseaRequisitionDTO, String userId) {
        ResponseResult checkResult = checkDataValidateCreate(overseaRequisitionDTO);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        String uuidRequisition = UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
        try {
            int addRequisitionResult = addOverseaRequisition(uuidRequisition, overseaRequisitionDTO, userId);
            if (addRequisitionResult < 1){
                throw new RuntimeException("创建领用申请表头错误");
            }

            int addRequisitionDtlResult = addOverseaRequisitionDtl(uuidRequisition, overseaRequisitionDTO);
            if (addRequisitionDtlResult < 1){
                throw new RuntimeException("创建领用申请明细错误");
            }

            iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_CREATE.getDescZh(), REQUISITION_CREATE.getDescEn(), "");
            if (REQUISITION_PENDING_APPROVAL.getCode().equals(overseaRequisitionDTO.getSpmsStatus())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_PENDING_APPROVAL.getDescZh(), REQUISITION_PENDING_APPROVAL.getDescEn(), "");
            }
            return getRequisitionAndDtl(uuidRequisition);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
        }
    }

    @Override
    public ResponseResult getRequisitionAndDtl(String uuidRequisition) {
        if (StringUtils.isEmpty(uuidRequisition)){
            return ResponseResult.error("请求参数不能为空");
        }
        return ResponseResult.success()
                .add("overseaRequisition", this.baseMapper.getOverseaRequisition(uuidRequisition))
                .add("overseaRequisitionDtlList", iOverseaRequisitionDtlService.getRequisitionDtlList(uuidRequisition));
    }

    ResponseResult checkDataValidateCreate(OverseaRequisitionDTO overseaRequisitionDTO){
        if (overseaRequisitionDTO == null || StringUtils.isEmpty(overseaRequisitionDTO.getCreateDate()) ||
                StringUtils.isEmpty(overseaRequisitionDTO.getSpmsStatus()) || StringUtils.isEmpty(overseaRequisitionDTO.getWerks()) ||
                        StringUtils.isEmpty(overseaRequisitionDTO.getWhsLocationCode()) || StringUtils.isEmpty(overseaRequisitionDTO.getWorkshopCode())){
            return ResponseResult.error("请求参数错误");
        }
        String spmsStatus = overseaRequisitionDTO.getSpmsStatus();
        if (!spmsStatus.equals(REQUISITION_TO_SUBMIT.getCode()) && !spmsStatus.equals(REQUISITION_PENDING_APPROVAL.getCode())){
            return ResponseResult.error("请求单据状态不正确");
        }
        List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = overseaRequisitionDTO.getRequisitionDtlDTOList();
        if (overseaRequisitionDtlDTOList == null || overseaRequisitionDtlDTOList.size() == 0){
            return ResponseResult.error("请求数据明细不能为空");
        }
        for (OverseaRequisitionDtlDTO overseaRequisitionDtlDTO : overseaRequisitionDtlDTOList){
            if (StringUtils.isEmpty(overseaRequisitionDtlDTO.getMaterialNo())){
                return ResponseResult.error("领用申请明细数据错误");
            }
        }
        return ResponseResult.success();
    }

    int addOverseaRequisition(String uuidRequisition, OverseaRequisitionDTO overseaRequisitionDTO, String userId){
        try {
            OverseaRequisition overseaRequisition = new OverseaRequisition();
            overseaRequisition.setUuidRequisition(uuidRequisition);
            overseaRequisition.setCreateDate(overseaRequisitionDTO.getCreateDate());
            overseaRequisition.setBusinessType(overseaRequisitionDTO.getBusinessType());
            overseaRequisition.setSpmsStatus(overseaRequisitionDTO.getSpmsStatus());
            overseaRequisition.setCreateUserid(userId);
            overseaRequisition.setWerks(overseaRequisitionDTO.getWerks());
            overseaRequisition.setWorkshopCode(overseaRequisitionDTO.getWorkshopCode());
            overseaRequisition.setWhsLocationCode(overseaRequisitionDTO.getWhsLocationCode());
            overseaRequisition.setRelateDocument(overseaRequisitionDTO.getRelateDocument());
            overseaRequisition.setCostCenter(overseaRequisitionDTO.getCostCenter());
            overseaRequisition.setCostCenterName(overseaRequisitionDTO.getCostCenterName());
            overseaRequisition.setRemarks(overseaRequisitionDTO.getRemarks());
            overseaRequisition.setComments(overseaRequisitionDTO.getComments());
            return this.baseMapper.insert(overseaRequisition);
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    int addOverseaRequisitionDtl(String uuidRequisition, OverseaRequisitionDTO overseaRequisitionDTO){
        int result = 0;
        try{
            List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = overseaRequisitionDTO.getRequisitionDtlDTOList();
            for (int i = 0; i < overseaRequisitionDtlDTOList.size(); i ++){
                OverseaRequisitionDtlDTO dtlDTO = overseaRequisitionDtlDTOList.get(i);
                OverseaRequisitionDtl overseaRequisitionDtl = new OverseaRequisitionDtl();
                overseaRequisitionDtl.setUuidRequisition(uuidRequisition);
                overseaRequisitionDtl.setItem((i + 1) * 10);
                overseaRequisitionDtl.setWerks(overseaRequisitionDTO.getWerks());
                overseaRequisitionDtl.setWorkshopCode(overseaRequisitionDTO.getWorkshopCode());
                overseaRequisitionDtl.setWhsLocationCode(overseaRequisitionDTO.getWhsLocationCode());
                overseaRequisitionDtl.setMaterialNo(dtlDTO.getMaterialNo());
                overseaRequisitionDtl.setApplyQtyBasicUnit(dtlDTO.getApplyQtyBasicUnit());
                overseaRequisitionDtl.setActualQtyBasicUnit(dtlDTO.getActualQtyBasicUnit());
                overseaRequisitionDtl.setBasicUnit(dtlDTO.getBasicUnit());
                overseaRequisitionDtl.setApplyQtyUnitSales(dtlDTO.getApplyQtyUnitSales());
                overseaRequisitionDtl.setActualQtyUnitSales(dtlDTO.getActualQtyUnitSales());
                overseaRequisitionDtl.setUnitSales(dtlDTO.getUnitSales());
                overseaRequisitionDtl.setRemarks(dtlDTO.getRemarks());
                overseaRequisitionDtl.setMovementType(dtlDTO.getMovementType());
                overseaRequisitionDtl.setActualMovementType(dtlDTO.getActualMovementType());
                result += iOverseaRequisitionDtlService.addRequisitionDtl(overseaRequisitionDtl);
            }
            return result;
        } catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult updateOverseaRequisition(OverseaRequisitionDTO dto, String userId) {
        ResponseResult checkResult = checkUpdateOverseaRequisition(dto);
        if (checkResult.getCode() != SUCCESS){
            return checkResult;
        }
        try {
            String uuidRequisition = dto.getUuidRequisition();
            String spmsStatus = dto.getSpmsStatus();
            QueryWrapper<OverseaRequisition> queryWrapper = new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition);

            for (int i = 0; i < dto.getRequisitionDtlDTOList().size(); i ++){
                int resp = iOverseaRequisitionDtlService.updateRequisitionDtl(dto.getRequisitionDtlDTOList().get(i));
                if (resp < 1){
                    throw new RuntimeException("领用申请明细数据更新出错，请刷新重试");
                }
            }

            OverseaRequisition requisition = this.baseMapper.selectOne(queryWrapper);
            requisition.setSpmsStatus(spmsStatus);
            requisition.setApprovalDate(dto.getApprovalDate());
            requisition.setCostCenter(dto.getCostCenter());
            requisition.setCostCenterName(dto.getCostCenterName());
            requisition.setRemarks(dto.getRemarks() == null ? "" : dto.getRemarks());
            requisition.setComments(dto.getComments() == null ? "" : dto.getComments());
            this.baseMapper.update(requisition, queryWrapper);

            if (spmsStatus.equals(REQUISITION_APPROVED.getCode())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_APPROVED.getDescZh(), REQUISITION_APPROVED.getDescEn(), "");
            }
            if(spmsStatus.equals(REQUISITION_PENDING_APPROVAL.getCode())) {
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_PENDING_APPROVAL.getDescZh(), REQUISITION_PENDING_APPROVAL.getDescEn(), "");
            }
            if(spmsStatus.equals(REQUISITION_TO_SUBMIT.getCode())) {
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_TO_SUBMIT.getDescZh(), REQUISITION_TO_SUBMIT.getDescEn(), "");
            }
            if(spmsStatus.equals(REQUISITION_REJECT.getCode())){
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_UPDATE.getDescZh(), REQUISITION_UPDATE.getDescEn(), "");
            }

            return getRequisitionAndDtl(uuidRequisition);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
        }
    }

    ResponseResult checkUpdateOverseaRequisition(OverseaRequisitionDTO dto){
        if (dto == null || dto.getRequisitionDtlDTOList() == null || dto.getRequisitionDtlDTOList().size() == 0){
            return ResponseResult.error("请求参数错误");
        }
        if (StringUtils.isEmpty(dto.getUuidRequisition()) || dto.getDataVersion() == null || StringUtils.isEmpty(dto.getSpmsStatus())){
            return ResponseResult.error("请求参数错误");
        }
        if (!dto.getSpmsStatus().equals(REQUISITION_APPROVED.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_PENDING_APPROVAL.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_TO_SUBMIT.getCode()) &&
                !dto.getSpmsStatus().equals(REQUISITION_REJECT.getCode())){
            return ResponseResult.error("单据目标状态禁止此操作");
        }
        if (dto.getSpmsStatus().equals(REQUISITION_APPROVED.getCode())){
            if (StringUtils.isEmpty(dto.getApprovalDate())){
                return ResponseResult.error("审批通过日期不允许为空");
            }
        }
        String uuidRequisition = dto.getUuidRequisition();
        OverseaRequisition requisition = this.baseMapper.selectOne(new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
        if (requisition == null || dto.getDataVersion().intValue() != requisition.getDataVersion()){
            return ResponseResult.error("请求数据已更新请刷新重试");
        }
        if (!REQUISITION_PENDING_APPROVAL.getCode().equals(requisition.getSpmsStatus())
                && !REQUISITION_TO_SUBMIT.getCode().equals(requisition.getSpmsStatus())
                && !REQUISITION_REJECT.getCode().equals(requisition.getSpmsStatus())){
            return ResponseResult.error("单据当前状态禁止此操作");
        }
        List<OverseaRequisitionDtlDTO> overseaRequisitionDtlDTOList = dto.getRequisitionDtlDTOList();
        if (overseaRequisitionDtlDTOList == null || overseaRequisitionDtlDTOList.size() == 0){
            return ResponseResult.error("领用申请明细不能为空");
        }
        return ResponseResult.success();
    }

    /**
     *  状态说明：单据状态(0已删除;1待提交;2待审批;3审批通过;4审批拒绝;5已生成出库任务;)。
     *  状态变化：2——4 审批拒绝；1——0，4——0 删除申请；
     * @param uuidRequisition
     * @param dataVersion
     * @param spmsStatus
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult cancelOverseaRequisition(String uuidRequisition, Integer dataVersion, String spmsStatus, String userId) {
        if (StringUtils.isEmpty(uuidRequisition) || dataVersion == null || StringUtils.isEmpty(spmsStatus)){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<OverseaRequisition> queryWrapper = new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition);
        OverseaRequisition overseaRequisition = this.baseMapper.selectOne(queryWrapper);
        if (overseaRequisition == null){
            return ResponseResult.error("请求领用申请不存在");
        }
        if (overseaRequisition.getDataVersion() != dataVersion.intValue()){
            return ResponseResult.error("请求数据已更新，请刷新后重试");
        }
        String currentStatus = overseaRequisition.getSpmsStatus();
        try {
            if (REQUISITION_PENDING_APPROVAL.getCode().equals(currentStatus)){
                if (!REQUISITION_REJECT.getCode().equals(spmsStatus)){
                    return ResponseResult.error("请求目标状态错误");
                }
                overseaRequisition.setSpmsStatus(spmsStatus);
                this.baseMapper.update(overseaRequisition, queryWrapper);
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_REJECT.getDescZh(), REQUISITION_REJECT.getDescEn(), "");
            } else if (REQUISITION_TO_SUBMIT.getCode().equals(currentStatus) || REQUISITION_REJECT.getCode().equals(currentStatus)) {
                if (!REQUISITION_DELETE.getCode().equals(spmsStatus)){
                    return ResponseResult.error("请求目标状态错误");
                }
                overseaRequisition.setSpmsStatus(spmsStatus);
                this.baseMapper.update(overseaRequisition, queryWrapper);
                iOverseaOperateLogService.addOverseaOperateLog(userId, uuidRequisition, REQUISITION_DELETE.getDescZh(), REQUISITION_DELETE.getDescEn(), "");
            } else {
                return ResponseResult.error("当前状态禁止此操作");
            }
            return getRequisitionAndDtl(uuidRequisition);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error("请求执行过程出错请重试").add("error", e.getMessage());
        }
    }

    @Override
    public OverseaRequisition getOverseaRequisition(String uuidRequisition) {
        if (StringUtils.isEmpty(uuidRequisition)){
            return null;
        }
        return this.baseMapper.selectOne(new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
    }

    @Override
    public int updateRequisition(OverseaRequisition overseaRequisition) {
        String uuidRequisition = overseaRequisition.getUuidRequisition();
        return this.baseMapper.update(overseaRequisition, new QueryWrapper<OverseaRequisition>().eq("UUID_REQUISITION", uuidRequisition));
    }

    /***
     待发货领用申请异常报表/审批通过未出库超过3天
     -- 领用申请单状态为 3(审批通过) 审批通过日期已超过 3 天；且没有出库任务；
     -- 领用申请单状态为 5(已生成出库任务) 审批通过日期已超过 3 天；无有效出库任务 或 有状态为 1 进行中的出库任务；
     */
    @Override
    public List<Map<String, Object>> getRequisitionOverdueReports(String werks, String currentDate) {
        return this.baseMapper.getRequisitionOverdue3(werks, currentDate);
    }
}
